home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 21
/
CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso
/
CUCD
/
Utilities
/
DTConvert
/
DTConvert.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-02-05
|
54KB
|
1,758 lines
/*
**
** $VER: DTConvert.c 1.6 (5.2.98)
** datatypes.library/Examples/DTConvert
**
** Converts file into another format using datatypes
**
** Main program and startup code
**
** Written 1996-1998 by Roland 'Gizzy' Mainz
**
*/
/* project includes */
#include "DTConvert.h"
#include "gui.h"
/* version string */
#include "DTConvert_rev.h"
/*****************************************************************************/
/* list of datatypes, used in gadtools listview gadget */
struct DTList
{
struct List dtl_List;
UWORD dtl_NumNodes;
APTR dtl_Pool;
};
/* single dtlist node */
struct DTNode
{
struct Node dtn_Node;
STRPTR dtn_DTName;
/* dynamic bufferspace follows here */
};
/*****************************************************************************/
/* shared libraries */
struct Library *UtilityBase = NULL;
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *DataTypesBase = NULL;
struct Library *AslBase = NULL;
struct Library *IconBase = NULL;
struct Library *WorkbenchBase = NULL;
/*****************************************************************************/
/* version_string */
STRPTR versionstring = VERSTAG;
/*****************************************************************************/
/* local prototypes */
static void DefaultSettings( void );
static void ClearRDA( void );
static void ScanRDA( void );
static void ScanToolTypes( TEXT ** );
static void FreeInitProjectResult( void );
static void ReadENVPrefs( void );
static BOOL CreateBasicResources( void );
static void DeleteBasicResources( void );
static BOOL OpenLibStuff( void );
static void CloseLibStuff( void );
static void RunTool( STRPTR );
static BOOL NewProject( STRPTR, STRPTR, BOOL, STRPTR, BOOL, STRPTR );
static struct DTList *CreateDTDescrList( BPTR, ULONG );
static void FreeDTDescrList( struct DTList * );
static struct DTNode *FindDTNodeByName( struct DTList *, STRPTR );
static void LockGUI( void );
static void UnlockGUI( void );
static STRPTR StringSave( STRPTR );
static STRPTR AllocStringBuff( ULONG );
static STRPTR UpdateString( STRPTR *, STRPTR );
static void FreeString( STRPTR );
static struct DiskObject *GetToolDiskObject( STRPTR );
static ULONG SumString( STRPTR );
/*****************************************************************************/
long main_retval,
main_retval2;
static struct RDArgs *startuprda;
/* mempool for strings */
static APTR StringPool;
/*****************************************************************************/
/* template for ReadArgs */
#define STARTUP_TEMPLATE "FROM=NAME=SRCNAME," \
"DESTDATATYPE=DATATYPE=DTN," \
"IFF/S," \
"TO=DESTNAME," \
"GUI/S," \
"PUBSCREEN/K"
#define ENV_TEMPLATE STARTUP_TEMPLATE /* equal because there are no /A switches */
static
struct
{
STRPTR srcname;
STRPTR destdatatype;
long *iff;
STRPTR destname;
long *gui;
STRPTR pubscreen;
} result;
static
struct
{
STRPTR srcname;
STRPTR destdatatype;
BOOL iff;
STRPTR destname;
BOOL gui;
STRPTR pubscreen;
} project;
/*****************************************************************************/
/****** DTConvert/DTConvert **************************************************
*
* NAME
* DTConvert -- DataTypes-based conversion tool
*
* FORMAT
* DTConvert [FROM|NAME|SRCNAME <file>]
* [DESTDATATYPE|DATATYPE|DTN <datatype>] [IFF]
* [TO|DESTNAME <file>] [GUI] [PUBSCREEN <public screen>]
*
* TEMPLATE
* FROM=NAME=SRCNAME,DESTDATATYPE=DATATYPE=DTN,IFF/S,TO=DESTNAME,
* GUI/S,PUBSCREEN/K
*
* PURPOSE
* Convert data from one format into another format using datatypes
* classes.
*
* DESCRIPTION
* DTConvert converts data from one format into another format,
* e.g. picture -> picture,
* animation -> anmation,
* movie -> movie,
* sound -> sound,
* text -> text (n/a)
*
* You simply have to set the souce file name (SRCNAME), the
* datatype to convert to (DATATYPE) (or the IFF switch if you want to
* convert into the base-IFF format and the destination file name (TO).
*
* BUGS
* - picture.datatype V43 interface not implemented.
* This causes that any encoder only runs in V42 mode any may
* only encode 8 bit data.
*
* - path names are limitted to 1024 chars, larger filenames may cause
* mailfunctions
*
* NOTES
* - picture.datatype V43 pixmap interface not supported.
*
* - text conversion not supported yet.
*
* TODO
* - picture.datatype V43 compatibility
*
* - text conversion
*
* - GUI and WB suppport
*
* HISTORY
* V1.1:
* - First release to dta@amigawolrd.com mailinglist.
*
* V1.2:
* - Added support for animation.datatype subclasses
*
* V1.3:
* - Minor fixes.
*
* V1.4
* - Added support for sound.datatype V40 subclasses, partial support
* for suggested sound.datatype V41 interface.
*
* - Added some usefull comments.
*
* - WriteAnimClass/WriteSoundClass now sets
* SetIoErr( ERROR_REQUIRED_ARGUMENT_MISSING ); if something goes
* wrong (this should abort the encoder; only ERROR_OBJECT_NOT_FOUND
* is accepted here).
*
* - Fixed some holes in the error handling.
*
* - GUI added.
*
* - Added WB support
*
* - Added ENV variable support; a local or global (ENV) variable
* "DTConvert" takes the same arguments as the shell template.
* Variable settings can be overridden by any argument.
*
* - Project split in seperate sources (e.g. main, GUI, converters)
*
* V1.5
* - Added the feature that the datatypes selection requester shows
* only entries which match the source group IDs
* (if a source has been already selected).
*
* - Added kluge which alows the conversion between GID_MOVIE
* and GID_ANIMATION datatypes (both are based on
* animation.datatype, here we have the same interface :-)
*
* - Fixed the bug that ConvertAnimation function did not deal
* with truecolor bitmaps (e.g. CyberGFX bitmaps for example,
* truecolor bitmaps are indicated by ADTA_NumColors == 0.
* Fixed.
*
* V1.6
* - Fixed the bug that ObtainDataTypeA was called for each
* INTUITICK if the datatype selection requester was open.
* Fixed.
*
*
* AUTHOR's REQUEST
* By releasing this program I do not place any obligations on you,
* feel free to share this program with your friends (and enemies).
*
* If you want to blame me, report any bugs, or wants a new version
* send your letter to:
* Roland Mainz
* Hohenstaufenstraße 8
* 52388 Nörvenich
* GERMANY
*
* Phone: (+49)(0)2426/901568
* Fax: (+49)(0)2426/901569
*
* EMAIL is also available:
* GISBURN@w-specht.rhein-ruhr.de
*
* If you want to send me attachments larger than 1MB (up to 5MB,
* more with my permission):
* Up to April 1998 I'm reachable using this email address, too:
* Reinhold.A.Mainz@KBV.DE
*
* | Please put your name and address in your mails !
* | German mailers should add their phone numbers.
* | See BUGS section above when submitting bug reports.
*
* Sorry, but I can only look once a week for mails.
* If you don't hear something from me within three weeks, please
* send your mail again (but watch about new releases) (problems with
* this email port are caused by reconfigurations, hackers, network
* problems etc.).
*
* The entire "DTConvert" package may be noncommercially
* redistributed, provided that the package is always distributed
* in it's complete form (including it's documentation). A small copy
* fee for media costs is okay but any kind of commercial distribution
* is strictly forbidden! Comments and suggestions how to improve
* this program are generally appreciated!
*
* Thanks to Matt Dillon for his DICE, David Junod for this datatypes
* environment and Olaf 'Olsen' Barthel for his help, ideas and some
* text clips from his documentations.
*
* SEE ALSO
*
******************************************************************************
*
*/
#ifdef _DCC
/* disable CTRL_C break support (DICE CTRL_C abort function) */
void chkabort( void )
{
}
/* DICE workbench entry */
long wbmain( struct WBStartup *wbstartup )
{
/* Call main like SAS-C */
return( (int)main( 0L, (STRPTR *)wbstartup ) );
}
#endif /* _DCC */
int main( int ac, STRPTR *av )
{
LONG numArgs,
x;
struct WBStartup *wbstartup;
struct WBArg *wbarg;
struct DiskObject *tooldobj,
*projectdobj;
BPTR oldToolLock = NULL,
oldProjectLock = NULL;
main_retval2 = 0L;
main_retval = RETURN_OK;
if( CreateBasicResources() )
{
DefaultSettings();
/* check if something goes wrong (ENV error etc.) */
if( main_retval == RETURN_OK )
{
/* Workbench */
if( ac == 0L )
{
wbstartup = (struct WBStartup *)av;
numArgs = wbstartup -> sm_NumArgs;
wbarg = wbstartup -> sm_ArgList;
if( *(wbarg[ 0 ] . wa_Name) )
{
if( wbarg[ 0 ] . wa_Lock )
{
oldToolLock = CurrentDir( (wbarg[ 0 ] . wa_Lock) );
}
if( tooldobj = GetToolDiskObject( (wbarg[ 0 ] . wa_Name) ) )
{
/* two possible cases when started from workbench ... */
if( numArgs < 2L )
{
/* ... first case, only our tool icon is given, create one project here */
ScanToolTypes( (STRPTR *)(tooldobj -> do_ToolTypes) );
/* check if something goes wrong (parsing error, etc.) */
if( main_retval == RETURN_OK )
{
RunTool( NULL );
}
FreeInitProjectResult();
}
else
{
/* ... second case, a couple of project icons are given, multiple projects will start from here */
for( x = 1L ; x < numArgs ; x++ )
{
if( wbarg[ x ] . wa_Lock )
{
oldProjectLock = CurrentDir( (wbarg[ x ] . wa_Lock) );
}
if( *(wbarg[ x ] . wa_Name) )
{
if( projectdobj = GetDiskObject( (wbarg[ x ] . wa_Name) ) )
{
ScanToolTypes( (STRPTR *)(tooldobj -> do_ToolTypes) );
ScanToolTypes( (STRPTR *)(projectdobj -> do_ToolTypes) );
/* check if something goes wrong (parsing error, etc.) */
if( main_retval == RETURN_OK )
{
RunTool( (wbarg[ x ] . wa_Name) );
}
FreeInitProjectResult();
DefaultSettings();
FreeDiskObject( projectdobj );
}
}
if( wbarg[ x ] . wa_Lock )
{
CurrentDir( oldProjectLock );
}
}
}
FreeDiskObject( tooldobj );
}
if( wbarg[ 0 ] . wa_Lock )
{
CurrentDir( oldToolLock );
}
}
}
else
{
/* CLI/Shell */
if( startuprda = ReadArgs( STARTUP_TEMPLATE, (LONG *)(&result), NULL ) )
{
/* did we get a CTRL_C signal ? */
if( !CheckSignal( SIGBREAKF_CTRL_C ) )
{
ScanRDA();
/* check if something goes wrong (parsing error, etc.) */
if( main_retval == RETURN_OK )
{
RunTool( NULL );
}
FreeInitProjectResult();
}
else
{
main_retval2 = ERROR_BREAK;
main_retval = RETURN_WARN;
}
FreeArgs( startuprda );
}
else
{
main_retval2 = IoErr();
main_retval = RETURN_FAIL;
}
}
}
DeleteBasicResources();
}
PrintFault( main_retval2, NAME );
SetIoErr( main_retval2 );
return( main_retval );
}
static
void DefaultSettings( void )
{
ClearRDA();
memset( (void *)(&project), 0, sizeof( project ) );
ReadENVPrefs();
}
static
void ReadENVPrefs( void )
{
struct RDArgs envvarrda =
{
NULL,
256L,
0L,
0L,
NULL,
0L,
NULL,
RDAF_NOPROMPT
};
TEXT varbuff[ 258 ];
envvarrda . RDA_Source . CS_Buffer = varbuff;
if( GetVar( NAME, varbuff, 256L, 0UL ) != (-1L) )
{
strcat( varbuff, "\n" );
if( ReadArgs( ENV_TEMPLATE, (LONG *)(&result), (&envvarrda) ) )
{
ScanRDA();
FreeArgs( (&envvarrda) );
}
else
{
main_retval2 = IoErr();
main_retval = RETURN_FAIL;
}
}
}
static
void ClearRDA( void )
{
memset( (void *)(&result), 0, sizeof( result ) );
}
static
void ScanRDA( void )
{
if( result . srcname )
{
UpdateString( (&(project . srcname)), (result . srcname) );
}
if( result . destdatatype )
{
UpdateString( (&(project . destdatatype)), (result . destdatatype) );
}
if( result . iff )
{
project . iff = TRUE;
}
if( result . destname )
{
UpdateString( (&(project . destname)), (result . destname) );
}
if( result . gui )
{
project . gui = TRUE;
}
if( result . pubscreen )
{
UpdateString( (&(project . pubscreen)), (result . pubscreen) );
}
ClearRDA();
}
static
void ScanToolTypes( TEXT **tt )
{
STRPTR s;
if( s = FindToolType( tt, "FROM" ) )
result . srcname = s;
if( s = FindToolType( tt, "NAME" ) )
result . srcname = s;
if( s = FindToolType( tt, "SRCNAME" ) )
result . srcname = s;
if( s = FindToolType( tt, "DESTDATATYPE" ) )
result . destdatatype = s;
if( s = FindToolType( tt, "DATATYPE" ) )
result . destdatatype = s;
if( s = FindToolType( tt, "DTN" ) )
result . destdatatype = s;
if( s = FindToolType( tt, "IFF" ) )
result . iff = (long *)s;
if( s = FindToolType( tt, "TO" ) )
result . destname = s;
if( s = FindToolType( tt, "DESTNAME" ) )
result . destname = s;
if( s = FindToolType( tt, "GUI" ) )
result . gui = (long *)s;
if( s = FindToolType( tt, "PUBSCREEN" ) )
result . pubscreen = s;
ScanRDA();
}
static
void FreeInitProjectResult( void )
{
FreeString( (project . srcname) );
FreeString( (project . destdatatype) );
FreeString( (project . destname) );
FreeString( (project . pubscreen) );
}
static
BOOL CreateBasicResources( void )
{
if( OpenLibStuff() )
{
if( StringPool = CreatePool( (MEMF_PUBLIC | MEMF_CLEAR), 128UL, 128UL ) )
{
return( TRUE );
#ifdef COMMENTED_OUT
DeletePool( StringPool );
#endif /* COMMENTED_OUT */
}
CloseLibStuff();
}
return( FALSE );
}
static
void DeleteBasicResources( void )
{
DeletePool( StringPool );
CloseLibStuff();
}
static
BOOL OpenLibStuff( void )
{
AttemptOpenLibrary( (&UtilityBase), NAME, "utility.library", 39UL );
AttemptOpenLibrary( (struct Library **)(&(GfxBase)), NAME, "graphics.library", 39UL );
AttemptOpenLibrary( (struct Library **)(&(IntuitionBase)), NAME, "intuition.library", 39UL );
AttemptOpenLibrary( (&GadToolsBase), NAME, "gadtools.library", 39UL );
AttemptOpenLibrary( (&DataTypesBase), NAME, "datatypes.library", 45UL );
AttemptOpenLibrary( (&IconBase), NAME, "icon.library", 39UL );
AttemptOpenLibrary( (&WorkbenchBase), NAME, "workbench.library", 39UL );
AttemptOpenLibrary( (&AslBase), NAME, "asl.library", 38UL );
if( UtilityBase && GfxBase && IntuitionBase && GadToolsBase && DataTypesBase && IconBase && WorkbenchBase && AslBase )
{
return( TRUE );
}
CloseLibStuff();
return( FALSE );
}
static
void CloseLibStuff( void )
{
CloseLibrary( AslBase );
CloseLibrary( WorkbenchBase );
CloseLibrary( IconBase );
CloseLibrary( DataTypesBase );
CloseLibrary( GadToolsBase );
CloseLibrary( (&(IntuitionBase -> LibNode)) );
CloseLibrary( (&(GfxBase -> LibNode)) );
CloseLibrary( UtilityBase );
}
static
void RunTool( STRPTR srcname )
{
STRPTR destname = project . destname;
STRPTR datatypename = project . destdatatype;
BOOL srcchanged = FALSE; /* srcname changed ? */
ULONG srcsum = SumString( srcname );
if( project . srcname )
{
srcname = project . srcname;
}
/* Check if datatype name is valid */
if( datatypename )
{
struct DataType *dtn;
if( dtn = ObtainDataTypeA( DTST_RAM, (APTR)datatypename, NULL ) )
{
ReleaseDataType( dtn );
}
else
{
datatypename = NULL;
}
}
/* GUI requested / required ? */
if( (project . gui) || (srcname == NULL) || (destname == NULL) || (datatypename == NULL) )
{
struct MsgPort *appport;
struct DTList *dtl;
struct DTNode *selecteddt;
if( appport = CreateMsgPort() )
{
BPTR srclock = NULL;
if( Strlen( srcname ) )
{
srclock = Lock( srcname, SHARED_LOCK );
}
if( dtl = CreateDTDescrList( srclock, 0UL ) )
{
PubScreenName = project . pubscreen; /* set pubscreen name for GadToolsBox's windows */
selecteddt = FindDTNodeByName( dtl, datatypename );
if( !SetupScreen() )
{
struct FileRequester *SrcFileReq = NULL,
*DestFileReq = NULL;
if( !OpenDTConvert_MAINWindow() )
{
BOOL done = FALSE;
struct IntuiMessage *imsg;
ULONG sigmask;
BOOL get_source = FALSE,
get_datatype = FALSE,
get_destination = FALSE;
BOOL convert = FALSE;
BOOL convertable = Strlen( srcname ) && selecteddt && Strlen( destname );
struct AppWindow *appwindow = NULL;
struct DiskObject *appdobj = NULL;
struct AppIcon *appicon = NULL;
/* Running on WB screen ? */
if( ((DTConvert_MAINWnd -> WScreen -> Flags) & SCREENTYPE) == WBENCHSCREEN )
{
appwindow = AddAppWindowA( 0UL, 0UL, DTConvert_MAINWnd, appport, NULL );
}
else
{
if( appdobj = GetDefDiskObject( WBPROJECT ) )
{
/* Not running on workbench screen ? - Create AppIcon for wb app support ! */
appicon = AddAppIconA( 0UL, 0UL, NAME, appport, NULL, appdobj, NULL );
}
}
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL, GTST_String, srcname, TAG_DONE );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DATATYPE ], DTConvert_MAINWnd, NULL, GTTX_Text, ((selecteddt)?(selecteddt -> dtn_Node . ln_Name):(NULL)), TAG_DONE );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL, GTST_String, destname, TAG_DONE );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_CONVERT ], DTConvert_MAINWnd, NULL, GA_Disabled, (!convertable), TAG_DONE );
/* Main event loop */
while( !done )
{
ULONG sigr;
sigmask = (1UL << (DTConvert_MAINWnd -> UserPort -> mp_SigBit)) | (1UL << (appport -> mp_SigBit));
if( DTConvert_DATATYPEWnd )
{
sigmask |= (1UL << (DTConvert_DATATYPEWnd -> UserPort -> mp_SigBit));
}
sigr = Wait( sigmask );
/* Maiain window */
if( sigr & (1UL << (DTConvert_MAINWnd -> UserPort -> mp_SigBit)) )
{
while( imsg = GT_GetIMsg( (DTConvert_MAINWnd -> UserPort) ) )
{
switch( imsg -> Class )
{
case IDCMP_CLOSEWINDOW:
{
done = TRUE;
}
break;
case IDCMP_REFRESHWINDOW:
{
GT_BeginRefresh( (imsg -> IDCMPWindow) );
GT_EndRefresh( (imsg -> IDCMPWindow), TRUE );
}
break;
case IDCMP_GADGETUP:
{
switch( G( (imsg -> IAddress) ) -> GadgetID )
{
case GD_SOURCE: break; /* NOP */
case GD_DATATYPE: break; /* NOP */
case GD_DESTINATION: break; /* NOP */
case GD_GET_SOURCE:
{
get_source = TRUE;
}
break;
case GD_GET_DATATYPE:
{
get_datatype = TRUE;
}
break;
case GD_GET_DESTINATION:
{
get_destination = TRUE;
}
break;
case GD_CONVERT:
{
convert = TRUE;
}
break;
case GD_CANCEL:
{
done = TRUE;
}
break;
}
}
break;
case IDCMP_VANILLAKEY:
{
switch( imsg -> Code )
{
case 's': /* Source */
ActivateGadget( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL );
break;
case 'S': /* Get Source */
get_source = TRUE;
break;
case 't': /* datatype */
case 'T': /* datatype */
get_datatype = TRUE;
break;
case 'd': /* Destination */
ActivateGadget( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL );
break;
case 'D': /* Get Destination */
get_destination = TRUE;
break;
case 'c': /* Convert */
case 'C': /* Convert */
{
convert = TRUE;
}
break;
case 'a': /* Cancel */
case 'A': /* Cancel */
{
done = TRUE;
}
break;
}
}
break;
}
GT_ReplyIMsg( imsg );
}
}
/* DatataTypes requester */
if( DTConvert_DATATYPEWnd )
{
if( sigr & (1UL << (DTConvert_DATATYPEWnd -> UserPort -> mp_SigBit)) )
{
BOOL dtdone = FALSE;
BOOL dtok = FALSE;
LONG oldselected,
selected;
GT_GetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL,
GTLV_Selected, (&oldselected),
TAG_DONE );
selected = oldselected;
while( imsg = GT_GetIMsg( (DTConvert_DATATYPEWnd -> UserPort) ) )
{
switch( imsg -> Class )
{
case IDCMP_CLOSEWINDOW:
{
dtdone = TRUE;
}
break;
case IDCMP_REFRESHWINDOW:
{
GT_BeginRefresh( (imsg -> IDCMPWindow) );
GT_EndRefresh( (imsg -> IDCMPWindow), TRUE );
}
break;
case IDCMP_GADGETUP:
{
switch( G( (imsg -> IAddress) ) -> GadgetID )
{
case GD_DATATYPEDT: break; /* NOP */
case GD_OKDT:
{
dtdone = dtok = TRUE;
}
break;
case GD_CANCELDT:
{
dtdone = TRUE;
}
break;
}
}
break;
case IDCMP_VANILLAKEY:
{
switch( imsg -> Code )
{
case 'o': /* Ok */
case 'O': /* Ok */
dtdone = dtok = TRUE;
break;
case 'c': /* Cancel */
case 'C': /* Cancel */
dtdone = TRUE;
break;
case 'd': /* DT Selection down */
{
selected++;
}
break;
case 'D': /* DT Selection up */
{
selected--;
}
break;
}
}
break;
case IDCMP_RAWKEY:
{
switch( imsg -> Code )
{
case 76: /* up */
{
if( (imsg -> Qualifier) & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
{
selected = 0L; /* top */
}
else
{
if( (imsg -> Qualifier) & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) )
{
selected -= 5L; /* page up */
}
else
{
selected--; /* previous entry */
}
}
}
break;
case 77: /* down */
{
if( (imsg -> Qualifier) & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
{
selected = dtl -> dtl_NumNodes; /* bottom */
}
else
{
if( (imsg -> Qualifier) & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) )
{
selected += 5L; /* page down */
}
else
{
selected++; /* next entry */
}
}
}
break;
}
}
break;
}
/* Check bounds */
if( selected < 0L )
{
selected = 0L;
}
else
{
if( selected > (LONG)(dtl -> dtl_NumNodes) )
{
selected = (LONG)(dtl -> dtl_NumNodes);
}
}
GT_ReplyIMsg( imsg );
}
if( selected != oldselected )
{
GT_SetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL,
GTLV_Selected, selected,
GTLV_MakeVisible, selected,
TAG_DONE );
}
if( dtok )
{
if( selecteddt = (struct DTNode *)GetNumNode( (&(dtl -> dtl_List)), selected ) )
{
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DATATYPE ], DTConvert_MAINWnd, NULL,
GTTX_Text, (selecteddt -> dtn_Node . ln_Name),
TAG_DONE );
}
}
if( dtdone )
{
CloseDTConvert_DATATYPEWindow();
}
}
}
/* appppwindow / appicon port */
if( sigr & (1UL << (appport -> mp_SigBit)) )
{
struct AppMessage *amsg;
while( amsg = (struct AppMessage *)GetMsg( appport ) )
{
switch( amsg -> am_Type )
{
case AMTYPE_APPWINDOW:
case AMTYPE_APPICON:
{
if( amsg -> am_NumArgs )
{
LockGUI();
if( (amsg -> am_NumArgs) == 1UL )
{
STRPTR name;
if( name = GetLockName( (amsg -> am_ArgList[ 0 ] . wa_Lock), (amsg -> am_ArgList[ 0 ] . wa_Name) ) )
{
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL, GTST_String, name, TAG_DONE );
FreeVec( name );
}
}
else
{
ULONG i;
for( i = 0UL ; i < (amsg -> am_NumArgs) ; i++ )
{
STRPTR name;
if( name = GetLockName( (amsg -> am_ArgList[ i ] . wa_Lock), (amsg -> am_ArgList[ i ] . wa_Name) ) )
{
NewProject( name, ((selecteddt)?(selecteddt -> dtn_DTName):(NULL)), (project . iff), destname, TRUE, (project . pubscreen) );
FreeVec( name );
}
}
}
UnlockGUI();
}
}
break;
}
ReplyMsg( (&(amsg -> am_Message)) );
}
}
/* prorocess collected events */
if( get_source || get_datatype || get_destination )
{
LockGUI();
if( get_source )
{
if( SrcFileReq == NULL )
{
SrcFileReq = (struct FileRequester *)AllocAslRequestTags( ASL_FileRequest,
ASLFR_Screen, (DTConvert_MAINWnd -> WScreen),
ASLFR_TitleText, "Open File...",
ASLFR_InitialLeftEdge, ((DTConvert_MAINWnd -> LeftEdge) + (DTConvert_MAINWnd -> BorderLeft) + 1UL),
ASLFR_InitialTopEdge, ((DTConvert_MAINWnd -> TopEdge) + (DTConvert_MAINWnd -> BorderTop) + 1UL),
ASLFR_DoPatterns, TRUE,
TAG_DONE );
}
if( SrcFileReq )
{
if( AslRequest( SrcFileReq, NULL ) )
{
ULONG buffsize;
STRPTR filebuffer;
buffsize = Strlen( (SrcFileReq -> fr_Drawer) ) + Strlen( (SrcFileReq -> fr_File) ) + 10UL;
if( filebuffer = (STRPTR)AllocVec( buffsize, MEMF_PUBLIC ) )
{
strcpy( filebuffer, (SrcFileReq -> fr_Drawer) );
AddPart( filebuffer, (SrcFileReq -> fr_File), buffsize );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL, GTST_String, filebuffer, TAG_DONE );
FreeVec( filebuffer );
}
}
}
get_source = FALSE;
}
if( get_datatype )
{
if( DTConvert_DATATYPEWnd == NULL )
{
if( !OpenDTConvert_DATATYPEWindow() )
{
GT_SetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL, GTLV_Labels, dtl, TAG_DONE );
}
}
get_datatype = FALSE;
}
if( get_destination )
{
if( DestFileReq == NULL )
{
DestFileReq = (struct FileRequester *)AllocAslRequestTags( ASL_FileRequest,
ASLFR_Screen, (DTConvert_MAINWnd -> WScreen),
ASLFR_TitleText, "Save File...",
ASLFR_InitialLeftEdge, ((DTConvert_MAINWnd -> LeftEdge) + (DTConvert_MAINWnd -> BorderLeft) + 1UL),
ASLFR_InitialTopEdge, ((DTConvert_MAINWnd -> TopEdge) + (DTConvert_MAINWnd -> BorderTop) + 1UL),
ASLFR_DoPatterns, TRUE,
ASLFR_DoSaveMode, TRUE,
TAG_DONE );
}
if( DestFileReq )
{
if( AslRequest( DestFileReq, NULL ) )
{
ULONG buffsize;
STRPTR filebuffer;
buffsize = Strlen( (DestFileReq -> fr_Drawer) ) + Strlen( (DestFileReq -> fr_File) ) + 10UL;
if( filebuffer = (STRPTR)AllocVec( buffsize, MEMF_PUBLIC ) )
{
strcpy( filebuffer, (DestFileReq -> fr_Drawer) );
AddPart( filebuffer, (DestFileReq -> fr_File), buffsize );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL, GTST_String, filebuffer, TAG_DONE );
FreeVec( filebuffer );
}
}
}
get_destination = FALSE;
}
UnlockGUI();
}
/* update */
GT_GetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL,
GTST_String, (&srcname),
TAG_DONE );
/* My quick hack to check if the src filename has been changed... */
srcchanged = (SumString( srcname ) != srcsum);
/* following block is experimental... */
if( srcchanged )
{
struct DTList *old_dtl = dtl;
/* Update checksum... */
srcsum = SumString( srcname );
if( srclock )
{
UnLock( srclock );
srclock = NULL;
}
if( Strlen( srcname ) )
{
srclock = Lock( srcname, SHARED_LOCK );
}
dtl = CreateDTDescrList( srclock, 0UL );
if( selecteddt )
{
selecteddt = FindDTNodeByName( dtl, (selecteddt -> dtn_DTName) );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DATATYPE ], DTConvert_MAINWnd, NULL,
GTTX_Text, ((selecteddt)?(selecteddt -> dtn_Node . ln_Name):("")),
TAG_DONE );
}
/* update DataTypes selection gadget */
if( DTConvert_DATATYPEWnd )
{
GT_SetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL, GTLV_Labels, dtl, TAG_DONE );
}
FreeDTDescrList( old_dtl );
}
GT_GetGadgetAttrs( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL,
GTST_String, (&destname),
TAG_DONE );
convertable = Strlen( srcname ) && selecteddt && Strlen( destname );
GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_CONVERT ], DTConvert_MAINWnd, NULL,
GA_Disabled, (!convertable),
TAG_DONE );
/* run converter ? */
if( convert )
{
if( convertable )
{
LockGUI();
Message( "converting '%s' '%s' '%s'\n", srcname, (selecteddt -> dtn_DTName), destname );
Convert( srcname, (selecteddt -> dtn_DTName), FALSE, destname );
UnlockGUI();
}
convert = FALSE;
}
}
if( appwindow )
{
(void)RemoveAppWindow( appwindow );
}
if( appdobj )
{
FreeDiskObject( appdobj );
}
if( appicon )
{
(void)RemoveAppIcon( appicon );
}
CloseDTConvert_DATATYPEWindow();
CloseDTConvert_MAINWindow();
}
FreeAslRequest( SrcFileReq );
FreeAslRequest( DestFileReq );
CloseDownScreen();
}
FreeDTDescrList( dtl );
}
if( srclock )
{
UnLock( srclock );
}
ClearMsgPort( appport );
DeleteMsgPort( appport );
}
}
else
{
Convert( srcname, datatypename, (project . iff), destname );
}
if( IoErr() )
{
main_retval2 = IoErr();
main_retval = RETURN_ERROR;
}
}
static
BOOL NewProject( STRPTR from, STRPTR datatype, BOOL iff, STRPTR destname, BOOL gui, STRPTR pubscreen )
{
struct Process *ThisProc = (struct Process *)FindTask( NULL );
BPTR oldir = CurrentDir( (ThisProc -> pr_HomeDir) );
BOOL success = FALSE;
STRPTR buffer;
ULONG buffersize;
struct CommandLineInterface *cli = Cli();
buffersize = Strlen( from ) + Strlen( datatype ) + Strlen( destname ) + Strlen( pubscreen ) + 512UL;
if( buffer = (STRPTR)AllocVec( buffersize, MEMF_PUBLIC ) )
{
STRPTR next = buffer;
if( cli )
{
STRPTR s = (STRPTR)BADDR( (cli -> cli_CommandName) );
stccpy( next, (&s[ 1 ]), (int)(s[ 0 ] + 1U) );
}
else
{
strcpy( next, (ThisProc -> pr_Task . tc_Node . ln_Name) );
}
next += strlen( next );
if( Strlen( from ) )
{
mysprintf( next, " FROM=\"%s\"", from );
next += strlen( next );
}
if( Strlen( datatype ) )
{
mysprintf( next, " DATATYPE=\"%s\"", datatype );
next += strlen( next );
}
if( iff )
{
mysprintf( next, " IFF" );
next += strlen( next );
}
if( Strlen( destname ) )
{
mysprintf( next, " TO=\"%s\"", destname );
next += strlen( next );
}
if( gui )
{
mysprintf( next, " GUI" );
next += strlen( next );
}
if( Strlen( pubscreen ) )
{
mysprintf( next, " PUBSCREEN=\"%s\"", pubscreen );
}
if( SystemTags( buffer,
SYS_Input, NULL,
SYS_Output, NULL,
SYS_Asynch, TRUE,
TAG_DONE ) != (-1L) )
{
success = TRUE;
}
FreeVec( buffer );
}
(void)CurrentDir( oldir );
return( success );
}
/* GUI locking stuff */
static ULONG GUILock = 0UL;
static struct Requester MAINBlockReq = { 0 };
static BOOL MAINBlockReqActive = FALSE;
static struct Requester DATATYPEBlockReq = { 0 };
static BOOL DATATYPEBlockReqActive = FALSE;
static
void LockGUI( void )
{
if( GUILock++ == 0UL )
{
InitRequester( (&MAINBlockReq) );
InitRequester( (&DATATYPEBlockReq) );
if( DTConvert_MAINWnd )
{
SetWindowPointer( DTConvert_MAINWnd, WA_BusyPointer, TRUE, WA_PointerDelay, TRUE, TAG_DONE );
if( MAINBlockReqActive == FALSE )
{
MAINBlockReqActive = Request( (&MAINBlockReq), DTConvert_MAINWnd );
}
}
if( DTConvert_DATATYPEWnd )
{
SetWindowPointer( DTConvert_DATATYPEWnd, WA_BusyPointer, TRUE, WA_PointerDelay, TRUE, TAG_DONE );
if( DATATYPEBlockReqActive == FALSE )
{
DATATYPEBlockReqActive = Request( (&DATATYPEBlockReq), DTConvert_DATATYPEWnd );
}
}
}
}
static
void UnlockGUI( void )
{
if( --GUILock == 0UL )
{
if( DTConvert_MAINWnd )
{
SetWindowPointer( DTConvert_MAINWnd, WA_BusyPointer, FALSE, TAG_DONE );
if( MAINBlockReqActive )
{
EndRequest( (&MAINBlockReq), DTConvert_MAINWnd );
MAINBlockReqActive = FALSE;
}
}
if( DTConvert_DATATYPEWnd )
{
SetWindowPointer( DTConvert_DATATYPEWnd, WA_BusyPointer, FALSE, TAG_DONE );
if( DATATYPEBlockReqActive )
{
EndRequest( (&DATATYPEBlockReq), DTConvert_DATATYPEWnd );
DATATYPEBlockReqActive = FALSE;
}
}
}
}
void Message( STRPTR fmt, ... )
{
VPrintf( fmt, (APTR)((&fmt) + 1) );
}
static
struct DTList *CreateDTDescrList( BPTR lock, ULONG groupid )
{
APTR pool;
#define NUM_GID_TABLE (32) /* we have much less GID_#? types defined yet (datatypes.library V45), but... */
ULONG groupid_table[ NUM_GID_TABLE ] = { 0 };
/* If a lock is given, we build here a list of all DT group ids the source file may be of... */
if( lock )
{
struct DataType *dtn,
*prevdtn = NULL;
/* Print whole list or determine the DataType of the file */
while( dtn = ObtainDataType( DTST_FILE, (APTR)lock, DTA_DataType, prevdtn,
XTAG( groupid, DTA_GroupID ), groupid,
TAG_DONE ) )
{
ULONG i,
groupid = dtn -> dtn_Header -> dth_GroupID;
/* Release previous DataType */
ReleaseDataType( prevdtn );
/* the follwoing statement assmes that GID_SYSTEM datatypes are not convertable
* (and it filters some invalid datatypes which have a 0 group id)
*/
if( (groupid != GID_SYSTEM) && (groupid != 0UL) )
{
for( i = 0UL ; i < NUM_GID_TABLE ; i++ )
{
if( !groupid_table[ i ] )
{
groupid_table[ i ] = groupid;
break;
}
}
}
prevdtn = dtn;
}
/* Release last datatype */
ReleaseDataType( prevdtn );
}
if( pool = CreatePool( (MEMF_PUBLIC | MEMF_CLEAR), 1024UL, 1024UL ) )
{
struct DTList *dtl;
if( dtl = (struct DTList *)AllocVecPooled( pool, sizeof( struct DTList ) ) )
{
struct DataType *dtn,
*prevdtn = NULL;
BOOL error = FALSE;
NewList( (&(dtl -> dtl_List)) );
dtl -> dtl_Pool = pool;
/* Print whole list or determine the DataType of the file */
while( dtn = ObtainDataType( DTST_RAM, NULL, DTA_DataType, prevdtn,
XTAG( groupid, DTA_GroupID ), groupid,
TAG_DONE ) )
{
struct DataTypeHeader *dth; /* datatypes header */
BOOL match = TRUE; /* include this datatype ? */
/* Release previous DataType */
ReleaseDataType( prevdtn );
dth = dtn -> dtn_Header; /* Shortcut... */
/* If we have a lock given, we previously build a group id table... */
if( lock )
{
ULONG i;
match = FALSE;
/* ... now check if this datatype node matches any source groupid */
for( i = 0UL ; ((i < NUM_GID_TABLE) && groupid_table[ i ]) ; i++ )
{
/* Match ? */
if( groupid_table[ i ] == (dth -> dth_GroupID) )
{
match = TRUE;
break;
}
/* Special kluge that we can convert GID_ANIMATION to GID_MOVIE and backwards
* (both are based on animation.datatype, here we have the same interface :-)
*/
if( ((groupid_table[ i ] == GID_MOVIE) || (groupid_table[ i ] == GID_ANIMATION)) &&
(((dth -> dth_GroupID) == GID_MOVIE) || ((dth -> dth_GroupID) == GID_ANIMATION)) )
{
match = TRUE;
break;
}
}
}
/* Include this datatype ? */
if( match )
{
STRPTR groupid_name; /* short-cut to GID_#? name string */
ULONG size; /* size of struct DTNode and contents */
struct DTNode *namenode;
groupid_name = GetDTString( (dth -> dth_GroupID) );
size = sizeof( struct DTNode ) + (strlen( (dth -> dth_Name) ) * 2UL) + Strlen( groupid_name ) + 16UL;
/* Alloc and build node... */
if( namenode = (struct DTNode *)AllocVecPooled( pool, size ) )
{
STRPTR s = (STRPTR)(namenode + 1);
/* store listview names */
mysprintf( s, "%s %s", (dth -> dth_Name), groupid_name );
namenode -> dtn_Node . ln_Name = s;
s = s + strlen( s ) + 2; /* next free space */
/* store datatype name */
strcpy( s, (dth -> dth_Name) );
namenode -> dtn_DTName = s;
/* add node */
AddTail( (&(dtl -> dtl_List)), (&(namenode -> dtn_Node)) );
dtl -> dtl_NumNodes++;
}
else
{
error = TRUE;
}
}
prevdtn = dtn;
}
/* Release last datatype */
ReleaseDataType( prevdtn );
/* Success ? */
if( !error )
{
return( dtl );
}
}
DeletePool( pool );
}
return( NULL );
}
static
void FreeDTDescrList( struct DTList *list )
{
if( list )
{
DeletePool( (list -> dtl_Pool) );
}
}
static
struct DTNode *FindDTNodeByName( struct DTList *list, STRPTR name )
{
struct DTNode *node;
struct DTNode *result = NULL;
if( list && name )
{
for( node = (struct DTNode *)(list -> dtl_List . lh_Head) ; node -> dtn_Node . ln_Succ ; node = (struct DTNode *)(node -> dtn_Node . ln_Succ) )
{
if( !Stricmp( (node -> dtn_DTName), name ) )
{
result = node;
break;
}
}
}
return( result );
}
static
STRPTR StringSave( STRPTR s )
{
STRPTR saved;
if( s )
{
if( saved = AllocStringBuff( (ULONG)strlen( s ) ) )
{
strcpy( saved, s );
return( saved );
}
}
return( NULL );
}
static
STRPTR AllocStringBuff( ULONG size )
{
return( (STRPTR)AllocVecPooled( StringPool, (size + 2UL) ) );
}
static
STRPTR UpdateString( STRPTR *storage, STRPTR newstring )
{
STRPTR s;
s = NULL;
if( storage )
{
FreeString( (*storage) );
s = (*storage) = StringSave( newstring );
}
return( s );
}
static
void FreeString( STRPTR s )
{
if( s )
{
FreeVecPooled( StringPool, s );
}
}
static
struct DiskObject *GetToolDiskObject( STRPTR name )
{
struct DiskObject *dobj;
struct Process *ThisProc = (struct Process *)FindTask( NULL );
BPTR olddir = CurrentDir( (ThisProc -> pr_HomeDir) );
dobj = GetDiskObjectNew( name );
(void)CurrentDir( olddir );
return( dobj );
}
static
ULONG SumString( STRPTR s )
{
ULONG sum = 0UL;
if( s )
{
ULONG ch;
while( ch = *s++ )
{
sum = (sum * 7UL) + ch;
}
}
return( sum );
}